package com.gitee.qdbp.base.utils;

import java.util.Locale;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.i18n.LocaleContext;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.LocaleResolver;
import com.gitee.qdbp.base.i18n.ResultCodeI18nResolver;

/**
 * 国际化工具类
 *
 * @author zhaohuihua
 * @version 181108
 */
public class I18nTools {

    /** 日志对象 **/
    private static Logger log = LoggerFactory.getLogger(ResultCodeI18nResolver.class);

    /**
     * Resolve the current locale via the request. <br>
     * Can return a default locale as fallback in any case.
     * 
     * @return the current locale (never {@code null})
     */
    public static Locale getLocale() {
        WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
        LocaleContext localeContext = LocaleContextHolder.getLocaleContext();
        Locale locale;
        if (localeContext != null) {
            locale = localeContext.getLocale();
            log.trace("Using LocaleContextHolder, the locale is {}.", locale);
        } else { // 如果在filter中调用, 则localeContext=null
            String resolverName = DispatcherServlet.LOCALE_RESOLVER_BEAN_NAME;
            LocaleResolver localeResolver = context.getBean(resolverName, LocaleResolver.class);
            if (localeResolver == null) {
                locale = LocaleContextHolder.getLocale(); // Locale.getDefault();
                log.debug("Unable to LocaleResolver with name '{}', using default locale({})", resolverName, locale);
            } else {
                locale = localeResolver.resolveLocale(WebTools.me.getRequest());
                log.trace("Using LocaleResolver {}, resolve locale({})", localeResolver, locale);
            }
        }
        return locale;
    }

    /**
     * Try to resolve the message. Treat as an error if the message can't be found.
     * 
     * @param code the code to lookup up, such as 'calculator.noRateSet'
     * @return the resolved message
     * @throws NoSuchMessageException if the message wasn't found
     * @see MessageSource#getMessage(String, Object[], String, Locale)
     */
    public static String getMessage(String code) throws NoSuchMessageException {
        Locale locale = getLocale();
        return getMessage(code, null, locale);
    }

    /**
     * Try to resolve the message. Treat as an error if the message can't be found.
     * 
     * @param code the code to lookup up, such as 'calculator.noRateSet'
     * @param args an array of arguments that will be filled in for params within the message (params look like "{0}",
     *            "{1,date}", "{2,time}" within a message), or {@code null} if none.
     * @return the resolved message
     * @throws NoSuchMessageException if the message wasn't found
     * @see MessageSource#getMessage(String, Object[], String, Locale)
     */
    public static String getMessage(String code, Object[] args) throws NoSuchMessageException {
        Locale locale = getLocale();
        MessageSource context = ContextLoader.getCurrentWebApplicationContext();
        return context.getMessage(code, args, locale);
    }

    /**
     * Try to resolve the message. Treat as an error if the message can't be found.
     * 
     * @param code the code to lookup up, such as 'calculator.noRateSet'
     * @param locale the locale in which to do the lookup
     * @return the resolved message
     * @throws NoSuchMessageException if the message wasn't found
     * @see MessageSource#getMessage(String, Object[], String, Locale)
     */
    public static String getMessage(String code, Locale locale) throws NoSuchMessageException {
        return getMessage(code, null, locale);
    }

    /**
     * Try to resolve the message. Treat as an error if the message can't be found.
     * 
     * @param code the code to lookup up, such as 'calculator.noRateSet'
     * @param args an array of arguments that will be filled in for params within the message (params look like "{0}",
     *            "{1,date}", "{2,time}" within a message), or {@code null} if none.
     * @param locale the locale in which to do the lookup
     * @return the resolved message
     * @throws NoSuchMessageException if the message wasn't found
     * @see MessageSource#getMessage(String, Object[], String, Locale)
     */
    public static String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException {
        MessageSource context = ContextLoader.getCurrentWebApplicationContext();
        return context.getMessage(code, args, locale);
    }
}
